//
//  WmcSelectAddressVC.swift
//  YPWatermarkCamera
//
//  Created by 周诗松 on 2022/4/9.
//

import UIKit
import MJRefresh
import YPBedrock
import Foundation
import AMapSearchKit
import AMapLocationKit
import AMapFoundationKit

// MARK: - WmcSelectAddressVC + WmcNavigatorProtocol

extension WmcSelectAddressVC: WmcNavigatorProtocol {
    static func navigationPaths() -> [WmcNavigatorManager.Path] {
        return [.selectAddress]
    }

    static func willMakeNavigationVC(with parms: WmcNavigatorManager.Parms) -> UIViewController {
        var vm = WmcSelectAddressVM()

        if let viewModel = parms.context as? WmcSelectAddressVM {
            vm = viewModel
        }

        let vc = WmcSelectAddressVC(vm)
        return vc
    }

    func willPushNavigationVC(startPushBlock: @escaping YPBlock.Empty, endOperationBlock: @escaping YPBlock.Empty) {
        YPDevice.PlayShake(.light)
        let locationStatus = WmcAuthorizedManager.location()
        if locationStatus.info.isAvailable {
            startPushBlock()
        } else {
//            WmcAuthorizedManager.showPrivacyAlert(type: .location)
            let alert = WmcAlertView()
            alert.title = "提示"
            alert.msg = "在您使用添加含有地理位置水印的功能时，需要您同意授权地理位置权限"
            let okTitle = locationStatus == .notDetermined ? "同意" : "去开启"
            let cancelTitle = locationStatus == .notDetermined ? "拒绝" : "取消"
            alert.style = .custom(confirmTitle: okTitle, cancelTitle: cancelTitle)
            alert.confirmBlock = {
                if locationStatus == .notDetermined {
                    WmcAuthorizedManager.locationRequest { [weak self] status in
                        guard let weakSelf = self else { return }
                        if status.info.isAvailable { // 有权限
                            WmcLocationManager.stopLocation()
                            WmcLocationManager.startLocation() { // 开始定位
                                startPushBlock()
                            }
                        } else {
                            endOperationBlock()
                        }
                    }
                } else {
                    WmcAuthorizedManager.openSetting()
                }
                
            }
            alert.show()
            endOperationBlock()
        }
    }
}

// MARK: - WmcSelectAddressVC + WmcVMProtocol

extension WmcSelectAddressVC: WmcVMProtocol {
    typealias VMType = WmcSelectAddressVM
}

// MARK: - [WmcSelectAddressVC]

class WmcSelectAddressVC: WmcBaseVC {
    // Lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()
        fetchData(showLoading: true)
    }

    // Internal

    override func bindViewAction() {
        tableView.mj_header = MJRefreshNormalHeader(refreshingBlock: { [weak self] in
            guard let weakSelf = self else { return }
            weakSelf.fetchData(showLoading: false)
        })

        tableView.mj_footer = MJRefreshBackNormalFooter(refreshingBlock: { [weak self] in
            guard let weakSelf = self else { return }
            weakSelf.loadMore()
        })

        let tap = UITapGestureRecognizer()
        addressLabel.addGestureRecognizer(tap)

        tap.rx.event.subscribe { [weak self] _ in
            guard let weakSelf = self else { return }

            weakSelf.searchTextField.resignFirstResponder()

            var list: [String] = []
            var index: Int?
            var addressPrefix: String?

            if weakSelf.viewModel.customLocation == nil {
                list = WmcLocationManager.shared.getAddressPrefixList()
                addressPrefix = WmcLocationManager.shared.addressPrefix
            } else {
                list = weakSelf.viewModel.customLocation?.addressPrefixList ?? []
                addressPrefix = weakSelf.viewModel.customLocation?.addressPrefix
            }

            if let addressPrefix = addressPrefix {
                if addressPrefix.isEmpty {
                    WmcHudManager.toast("未获取到地址")
                    return
                }
                index = list.firstIndex(of: addressPrefix)
            } else {
                WmcHudManager.toast("未获取到地址")
                return
            }

            let sheet = WmcSheetView()
            sheet.title = "设置地址显示级别"
            sheet.items = list
            sheet.selectedIndex = index
            sheet.show()
            sheet.didSelectIndexBlock = { [weak self] index in
                guard let weakSelf = self else { return }
                if index < list.count {
                    let text = list[index]
                    weakSelf.addressLabel.text = text
                    if weakSelf.viewModel.customLocation == nil {
                        WmcLocationManager.setAddressPrefix(text)
                    } else {
                        weakSelf.viewModel.customLocation?.addressPrefix = text
                        if let addressModel = weakSelf.viewModel.customLocation?.selectedAddress {
                            addressModel.addressPrefix = text
                            weakSelf.viewModel.selectAddress?(addressModel)
                        }
                    }
                }
            }

        }.disposed(by: rx.disposeBag)

        locationQuestionBtn.rx.controlEvent(.touchUpInside).subscribe { _ in
            // 调用优化之后的h5页面
            let vm = WmcHtml5VM()
            vm.parameters = nil
            vm.questionType = .LocatingType
            vm.path = WmcHtml5VM.Html5Path.feedback
            WmcNavigatorManager.push(.html5Page, parms: vm)
        }.disposed(by: rx.disposeBag)

        updateBtn.yp.addEvent { [weak self] btn in
            guard let weakSelf = self,
                  let imageView = btn.imageView else { return }
            imageView.yp.makeAnimation { make in
                make.springAnimation(.transform_rotation) { make in
                    make.set(fromValue: 0)
                        .set(toValue: 360.yp.angleToRadian)
                        .set(duration: 1.2)
                }
            }
            weakSelf.tableView.mj_header?.beginRefreshing()
        }

        clearBtn.yp.addEvent { [weak self] _ in
            guard let weakSelf = self else { return }
            weakSelf.searchTextField.text = nil
            weakSelf.clearBtn.isHidden = true
            weakSelf.viewModel.searchKeyword = nil
            weakSelf.fetchData(showLoading: true)
        }
    }

    override func makeUI() {
        title = "选择地址"
        makeNavView(showShadow: false)
        navView.addSubview(locationQuestionBtn)
        navView.addSubview(updateBtn)

        addSubview(grayView)
        addSubview(addressLabel)
        addSubview(arrowView)
        addSubview(addressDetailLabel)
        addSubview(locationView)
        addSubview(searchView)
        addSubview(emptyView)
        addSubview(tableView)
        locationView.addSubview(locationIconView)
        locationView.addSubview(locationTipLabel)
        searchView.addSubview(searchIconView)
        searchView.addSubview(searchTextField)
        searchView.addSubview(clearBtn)

        locationQuestionBtn.snp.makeConstraints { make in
            make.right.equalTo(updateBtn.snp.left).offset(-20)
            make.centerY.height.equalTo(navView.backImageView)
            make.width.equalTo(85)
        }

        updateBtn.snp.makeConstraints { make in
            make.right.equalTo(-16)
            make.centerY.height.equalTo(navView.backImageView)
            make.width.equalTo(58)
        }

        grayView.snp.makeConstraints { make in
            make.top.equalTo(navView.snp.bottom)
            make.left.right.equalToSuperview()
            make.height.equalTo(5)
        }

        let addressLabelMaxWidth = UIScreen.main.bounds.width - 48
        addressLabel.snp.makeConstraints { make in
            make.top.equalTo(grayView.snp.bottom).offset(12)
            make.left.equalTo(16)
            make.width.lessThanOrEqualTo(addressLabelMaxWidth)
            make.height.equalTo(25)
        }

        arrowView.snp.makeConstraints { make in
            make.left.equalTo(addressLabel.snp.right).offset(4)
            make.centerY.equalTo(addressLabel.snp.centerY)
            make.width.height.equalTo(18)
        }

        addressDetailLabel.snp.makeConstraints { make in
            make.left.equalTo(addressLabel.snp.left)
            make.top.equalTo(addressLabel.snp.bottom)
            make.right.equalTo(-16)
            make.height.equalTo(17)
        }

        locationView.snp.makeConstraints { make in
            make.left.right.equalToSuperview()
            make.height.equalTo(40)
            make.top.equalTo(addressDetailLabel.snp.bottom).offset(16)
        }

        locationIconView.snp.makeConstraints { make in
            make.left.equalTo(16)
            make.centerY.equalToSuperview()
            make.width.height.equalTo(24)
        }

        locationTipLabel.snp.makeConstraints { make in
            make.left.equalTo(locationIconView.snp.right).offset(4)
            make.centerY.equalToSuperview()
            make.right.equalTo(-16)
        }

        searchView.snp.makeConstraints { make in
            make.top.equalTo(locationView.snp.bottom).offset(16)
            make.left.equalTo(16)
            make.right.equalTo(-16)
            make.height.equalTo(34)
        }

        emptyView.snp.makeConstraints { make in
            make.top.equalTo(searchView.snp.bottom).offset(90)
            make.centerX.equalToSuperview()
        }

        searchIconView.snp.makeConstraints { make in
            make.left.equalTo(5)
            make.centerY.equalToSuperview()
            make.width.height.equalTo(18)
        }

        searchTextField.snp.makeConstraints { make in
            make.left.equalTo(searchIconView.snp.right).offset(4)
            make.right.equalTo(clearBtn.snp.left).offset(-6)
            make.top.equalTo(7)
            make.bottom.equalTo(-7)
        }

        clearBtn.snp.makeConstraints { make in
            make.right.equalTo(-10)
            make.centerY.equalToSuperview()
            make.width.height.equalTo(20)
        }

        tableView.snp.makeConstraints { make in
            make.top.equalTo(searchView.snp.bottom).offset(10)
            make.left.right.bottom.equalToSuperview()
        }
    }
    
    override func bindViewModel() {
        super.bindViewModel()
        WmcLocationManager.shared.poiStatus.subscribe(onNext: {
            [weak self] _ in
            guard let self = self else { return }
            if let addressPrefix = WmcLocationManager.shared.addressPrefix,
                self.viewModel.customLocation == nil {
                self.addressLabel.text = addressPrefix
            }
        }).disposed(by: rx.disposeBag)
    }
    
    

    // Private

    private lazy var locationQuestionBtn: UIButton = {
        let btn = UIButton(type: .custom)
        btn.setTitle("定位问题", for: .normal)
        btn.setTitleColor(.wmc_grayH4_5E6063, for: .normal)
        btn.setImage("location_question".wmc_image, for: .normal)
        btn.titleLabel?.font = 14.wmc_font
        return btn
    }()

    private lazy var updateBtn: UIButton = {
        let btn = UIButton(type: .custom)
        btn.setTitle("刷新", for: .normal)
        btn.setTitleColor(.wmc_grayH4_5E6063, for: .normal)
        btn.setImage("location_update".wmc_image, for: .normal)
        btn.titleLabel?.font = 14.wmc_font
        return btn
    }()

    private lazy var grayView: UIView = {
        let view = UIView()
        view.backgroundColor = .wmc_grayH20_F7F7F7
        return view
    }()

    private lazy var addressLabel: UILabel = {
        let label = UILabel()
        label.text = WmcLocationManager.shared.addressPrefix ?? "未获取到地址"
        label.textColor = .wmc_grayH3_505050
        label.font = 18.yp.uiFont(weight: .medium)
        label.isUserInteractionEnabled = true
        return label
    }()

    private lazy var arrowView: UIImageView = {
        let view = UIImageView(image: "small_arrow_right".wmc_image)
        return view
    }()

    private lazy var addressDetailLabel: UILabel = {
        let label = UILabel()
        label.text = "可设置到省/区/县/镇/乡/街道..."
        label.textColor = .wmc_grayH12_A0A0A0
        label.font = 12.wmc_font
        return label
    }()

    private lazy var locationView: UIView = {
        let view = UIView()
        view.backgroundColor = .wmc_blue_E5EFFF
        return view
    }()

    private lazy var locationIconView: UIImageView = {
        let view = UIImageView(image: "location_icon".wmc_image)
        return view
    }()

    private lazy var locationTipLabel: UILabel = {
        let label = UILabel()
        label.text = "【位置校准】只能选取附近200米以内的地址"
        label.textColor = .wmc_mainTheme
        label.font = 14.wmc_font
        return label
    }()

    private lazy var searchView: UIView = {
        let view = UIView()
        view.backgroundColor = .wmc_grayH20_F7F7F7
        view.layer.cornerRadius = 2
        return view
    }()

    private lazy var searchIconView: UIImageView = {
        let view = UIImageView(image: "location_search".wmc_image)
        return view
    }()

    private lazy var searchTextField: UITextField = {
        let textField = UITextField()
        textField.delegate = self
        textField.font = 14.yp.uiFont
        textField.textColor = .wmc_blackH1_000000
        textField.placeholder = "搜索附近地点"
        textField.returnKeyType = .search
        textField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
        return textField
    }()

    private lazy var clearBtn: UIButton = {
        let btn = UIButton(type: .custom)
        btn.setImage("close".wmc_image.yp.set(tintColor: UIColor.wmc_grayH3_505050), for: .normal)
        btn.isHidden = true
        return btn
    }()

    private lazy var tableView: UITableView = {
        let view = UITableView(frame: CGRect.zero, style: .plain)
        view.backgroundColor = .wmc_white_FFFFFF
        view.separatorStyle = .none
        view.delegate = self
        view.dataSource = self
        view.register(WmcSelectAddressCell.self, forCellReuseIdentifier: "WmcSelectAddressCell")
        view.register(WmcAddCustomAddressCell.self, forCellReuseIdentifier: "WmcAddCustomAddressCell")
        view.register(UITableViewCell.self, forCellReuseIdentifier: "UITableViewCell")
        return view
    }()

    private lazy var emptyView: WmcSelectAddressEmptyView = {
        let view = WmcSelectAddressEmptyView()
        view.isHidden = true
        return view
    }()

    @objc
    private func textFieldDidChange(_ sender: UITextField) {
        clearBtn.isHidden = (sender.text ?? "").isEmpty
    }

    private func fetchData(showLoading: Bool = true) {
        if viewModel.customLocation == nil {
            addressLabel.text = WmcLocationManager.shared.addressPrefix ?? "未获取到地址"
        } else {
            addressLabel.text = viewModel.customLocation?.addressPrefix ?? "未获取到地址"
        }

        if showLoading {
            WmcHudManager.loading()
        }

        viewModel.refresh { [weak self] list in
            guard let weakSelf = self else { return }
            if showLoading {
                WmcHudManager.dismiss()
            }

            weakSelf.tableView.reloadData()
            weakSelf.tableView.mj_header?.endRefreshing()
            if weakSelf.viewModel.hasNoMore {
                weakSelf.tableView.mj_footer?.endRefreshingWithNoMoreData()
            } else {
                weakSelf.tableView.mj_footer?.resetNoMoreData()
            }

            weakSelf.tableView.isHidden = weakSelf.viewModel.dataSource.isEmpty
            weakSelf.emptyView.isHidden = !weakSelf.viewModel.dataSource.isEmpty
            if !weakSelf.emptyView.isHidden {
                if let searchKeyword = weakSelf.viewModel.searchKeyword, !searchKeyword.isEmpty {
                    weakSelf.emptyView.status = .keywords
                } else {
                    weakSelf.emptyView.status = .all
                }
            }

        } failure: { [weak self] error in
            guard let weakSelf = self else { return }
            if showLoading {
                WmcHudManager.dismiss()
            }
            weakSelf.tableView.mj_header?.endRefreshing()
            weakSelf.tableView.reloadData()
            WmcHudManager.toast("获取定位失败，请检查网络状态")
        }
    }

    private func loadMore() {
        viewModel.loadMore { [weak self] list in
            guard let weakSelf = self else { return }
            weakSelf.tableView.reloadData()
            if weakSelf.viewModel.hasNoMore {
                weakSelf.tableView.mj_footer?.endRefreshingWithNoMoreData()
            } else {
                weakSelf.tableView.mj_footer?.endRefreshing()
            }

            weakSelf.tableView.isHidden = weakSelf.viewModel.dataSource.isEmpty
            weakSelf.emptyView.isHidden = !weakSelf.viewModel.dataSource.isEmpty
            if !weakSelf.emptyView.isHidden {
                if let searchKeyword = weakSelf.viewModel.searchKeyword, !searchKeyword.isEmpty {
                    weakSelf.emptyView.status = .keywords
                } else {
                    weakSelf.emptyView.status = .all
                }
            }

        } failure: { [weak self] error in
            guard let weakSelf = self else { return }
            weakSelf.tableView.mj_footer?.endRefreshing()
            WmcHudManager.toast("网络不佳，请稍后再试")
        }
    }

    private func setSelectedAddress(_ model: WmcSelectAddressModel) {
        guard let currentLocation = WmcAmapLocationManager.shared.location.value?.location else {
            return WmcHudManager.toast("设置失败，未获取到当前定位")
        }

        if viewModel.customLocation == nil {
            model.addressPrefix = WmcLocationManager.shared.addressPrefix
        } else {
            model.addressPrefix = viewModel.customLocation?.addressPrefix
        }

        viewModel.selectAddress?(model)

        if viewModel.customLocation == nil {
            let setSelectedPOI: () -> Void = { [weak self] in
                guard let weakSelf = self else { return }
                if model.style == .normal, weakSelf.viewModel.isShowSetCommonAddress {
                    WmcTaskSchedulerManager.shared.commonAddress = model.poi
                }
                WmcLocationManager.setSelectedPOI(model)
                weakSelf.navigationController?.popViewController(animated: true)
            }

            if model.style == .customized {
                setSelectedPOI()
            } else {
                let selectedLocation = CLLocation(latitude: model.poi.location.latitude, longitude: model.poi.location.longitude)
                let distance: Double = selectedLocation.distance(from: currentLocation)
                if distance <= 200 {
                    setSelectedPOI()
                } else {
                    WmcHudManager.toast("位置发生改变，请刷新列表再试")
                    DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
                        guard let weakSelf = self else { return }
                        weakSelf.fetchData(showLoading: true)
                    }
                }
            }
        } else {
            navigationController?.popViewController(animated: true)
        }
    }
}

// MARK: UITableViewDelegate, UITableViewDataSource

extension WmcSelectAddressVC: UITableViewDelegate, UITableViewDataSource {
    func numberOfSections(in _: UITableView) -> Int {
        return 1
    }

    func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int {
        return viewModel.dataSource.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let model = viewModel.dataSource.yp.object(at: indexPath.row) else {
            let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath)
            return cell
        }

        if model.style == .normal || model.style == .commonly || model.style == .customized {
            let cell: WmcSelectAddressCell = tableView.dequeueReusableCell(withIdentifier: "WmcSelectAddressCell", for: indexPath) as! WmcSelectAddressCell
            cell.bindModel(model, index: indexPath.row)

            cell.setCommonlyAddress = { [weak self] (isCommonly, index) in
                guard let weakSelf = self else { return }
                if index < weakSelf.viewModel.dataSource.count {
                    var style: WmcSelectAddressModel.Style = .normal

                    if isCommonly {
                        WmcHudManager.toast("已设为常用地址")
                        style = .commonly
                    }

                    if let temp = weakSelf.viewModel.dataSource.yp.object(at: index) {
                        temp.style = style
                    }
                    weakSelf.viewModel.sortList()
                    weakSelf.tableView.reloadData()
                }
            }

            cell.delCustomizedAddress = { [weak self] index in
                guard let weakSelf = self, let addressModel = weakSelf.viewModel.dataSource.yp.object(at: index) else { return }

                // 判断删除的点是否是全局设置的位置
                let isSame = WmcLocationManager.shared.poiStatus.value?.data?.poi.uid == addressModel.poi.uid

                weakSelf.viewModel.delCustomAddress(index)

                if weakSelf.viewModel.customLocation != nil {
                    var model: WmcSelectAddressModel?
                    if isSame {
                        // 重置数据
                        WmcLocationManager.shared.resetSelectedAddress()
                        // 重启定位
                        WmcLocationManager.shared.restartLocationService()

                        if addressModel.isSelected {
                            // 重置当前页面选中的地点
                            model = WmcLocationManager.shared.poiStatus.value?.data
                            weakSelf.viewModel.customLocation?.takePhotoAddress = model
                        }

                    } else if let takePhotoAddress = weakSelf.viewModel.customLocation?.takePhotoAddress, addressModel.isSelected {
                        model = takePhotoAddress
                    }

                    if let model = model {
                        weakSelf.viewModel.selectAddress?(model)
                        for (_, item) in weakSelf.viewModel.dataSource.enumerated() {
                            item.isSelected = item.poi.uid == model.poi.uid
                        }
                    }

                    weakSelf.tableView.reloadData()
                } else if isSame {
                    WmcLocationManager.shared.resetSelectedAddress()
                    weakSelf.fetchData(showLoading: true)
                } else {
                    weakSelf.tableView.reloadData()
                }
            }

            return cell
        } else if model.style == .settingCustom {
            let cell: WmcAddCustomAddressCell = tableView.dequeueReusableCell(withIdentifier: "WmcAddCustomAddressCell", for: indexPath) as! WmcAddCustomAddressCell
            cell.bindModel(model, index: indexPath.row)

            cell.setCustomAddress = { [weak self] index in
                guard let weakSelf = self else { return }

                if index < weakSelf.viewModel.dataSource.count {
                    if let model = weakSelf.viewModel.dataSource.yp.object(at: index) {
                        model.style = .customized
                        weakSelf.setSelectedAddress(model)
                    }
                }
            }

            return cell
        } else {
            let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath)
            return cell
        }
    }

    func tableView(_: UITableView, heightForRowAt _: IndexPath) -> CGFloat {
        return 71
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        guard let model = viewModel.dataSource.yp.object(at: indexPath.row) else { return }

        if model.style == .settingCustom {
            return
        }

        setSelectedAddress(model)
    }

    private func searchKeywordDidChange(_ text: String?) -> Bool {
        if (text == "" || text == nil), (viewModel.searchKeyword == "" || viewModel.searchKeyword == nil) {
            return false
        }

        let result = text != viewModel.searchKeyword

        return result
    }
}

// MARK: UITextFieldDelegate

extension WmcSelectAddressVC: UITextFieldDelegate {
    func textFieldDidEndEditing(_ textField: UITextField) {
        if searchKeywordDidChange(textField.text) {
            viewModel.searchKeyword = textField.text
            fetchData(showLoading: true)
        }
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        if searchKeywordDidChange(textField.text) {
            viewModel.searchKeyword = textField.text
            fetchData(showLoading: true)
        }
        textField.resignFirstResponder()
        return true
    }
}
